EN ESTA SECCIÓN
El análisis de países mediante técnicas de aprendizaje no supervisado permite identificar patrones y similitudes que no son evidentes mediante métodos tradicionales. En este estudio, aplicamos Análisis de Componentes Principales (ACP) y métodos de clusterización utilizando datos del Banco Mundial.
Los objetivos principales de este trabajo son:
Los datos utilizados provienen del World Development Indicators del Banco Mundial.
Base <- read_csv("f36a5086-3311-4b1a-9f0c-bda5cd4718df_Series - Metadata.csv",
show_col_types = FALSE)
Base_2022 <- Base %>%
select(
Pais = `Country Name`,
Codigo = `Country Code`,
PIB_per = `GDP per capita (current US$) [NY.GDP.PCAP.CD]`,
Poblacion = `Population, total [SP.POP.TOTL]`,
`Esperanza vida` = `Life expectancy at birth, total (years) [SP.DYN.LE00.IN]`,
`Acceso electricidad` = `Access to electricity (% of population) [EG.ELC.ACCS.ZS]`,
`Area boscosa` = `Forest area (% of land area) [AG.LND.FRST.ZS]`,
`Suscripciones movil` = `Mobile cellular subscriptions (per 100 people) [IT.CEL.SETS.P2]`,
`Crecimiento PIB` = `GDP growth (annual %) [NY.GDP.MKTP.KD.ZG]`,
`Mortalidad infantil` = `Mortality rate, infant (per 1,000 live births) [SP.DYN.IMRT.IN]`,
`Inversion extranjera` = `Foreign direct investment, net inflows (% of GDP) [BX.KLT.DINV.WD.GD.ZS]`,
`Gasto salud` = `Current health expenditure (% of GDP) [SH.XPD.CHEX.GD.ZS]`,
`Uso internet` = `Individuals using the Internet (% of population) [IT.NET.USER.ZS]`,
Importaciones = `Imports of goods and services (% of GDP) [NE.IMP.GNFS.ZS]`,
Exportaciones = `Exports of goods and services (% of GDP) [NE.EXP.GNFS.ZS]`,
`Tierra cultivable` = `Arable land (% of land area) [AG.LND.ARBL.ZS]`,
`Crecimiento poblacion` = `Population growth (annual %) [SP.POP.GROW]`,
Industria = `Industry (including construction), value added (% of GDP) [NV.IND.TOTL.ZS]`,
Remesas = `Personal remittances, received (% of GDP) [BX.TRF.PWKR.DT.GD.ZS]`
)
Base_2022[Base_2022 == ".."] <- NA
Base_2022 <- Base_2022 %>%
mutate(across(-c(Pais, Codigo), as.numeric)) %>%
drop_na() %>%
filter(!Pais %in% c("World", "High income", "Low income", "European Union",
"Latin America & Caribbean", "Middle income", "OECD members",
"East Asia & Pacific", "Sub-Saharan Africa", "South Asia",
"North America", "Euro area", "Arab World", "West Bank and Gaza",
"Lower middle income", "Upper middle income",
"Least developed countries: UN classification",
"Fragile and conflict affected situations",
"Heavily indebted poor countries (HIPC)",
"IDA total", "Low & middle income", "Middle East & North Africa",
"Pacific island small states", "Small states",
"Caribbean small states", "Other small states",
"IDA & IBRD total", "IDA only", "IBRD only",
"Pre-demographic dividend", "Post-demographic dividend",
"Early-demographic dividend", "Late-demographic dividend")) %>%
filter(Pais != "Luxembourg")variables_numericas <- names(Base_2022)[3:ncol(Base_2022)]
crear_tabla_unificada <- function(data, variable) {
valores <- data[[variable]]
total_paises <- sum(!is.na(valores))
media <- round(mean(valores, na.rm = TRUE), 2)
mediana <- round(median(valores, na.rm = TRUE), 2)
desv_est <- round(sd(valores, na.rm = TRUE), 2)
q1 <- round(quantile(valores, 0.25, na.rm = TRUE), 2)
q3 <- round(quantile(valores, 0.75, na.rm = TRUE), 2)
minimo <- round(min(valores, na.rm = TRUE), 2)
maximo <- round(max(valores, na.rm = TRUE), 2)
top10 <- data %>%
select(Pais, Valor = all_of(variable)) %>%
arrange(desc(Valor)) %>%
head(10) %>%
mutate(
Ranking = row_number(),
Pct_vs_Media = round((Valor / media - 1) * 100, 1)
)
estadisticas <- data.frame(
Métrica = c("Total Países", "Media", "Mediana", "Desv. Est.",
"Q1", "Q3", "Mínimo", "Máximo"),
Valor = c(total_paises, media, mediana, desv_est, q1, q3, minimo, maximo)
)
top10_tabla <- top10 %>%
mutate(
Pct_Display = paste0(ifelse(Pct_vs_Media >= 0, "+", ""), Pct_vs_Media, "%"),
Pct_Color = ifelse(Pct_vs_Media >= 0, "#00e676", "#ff1744")
) %>%
select(Ranking, País = Pais, Valor, Pct_Display, Pct_Color)
list(estadisticas = estadisticas, top10 = top10_tabla)
}for (variable in variables_numericas) {
cat(sprintf('\n\n#### %s {.unnumbered}\n\n', variable))
datos <- crear_tabla_unificada(Base_2022, variable)
cat('<div class="two-column-layout">\n\n')
cat('<div class="table-container">\n\n')
cat('<p class="section-title"> Estadísticas Globales</p>\n\n')
tabla_stats <- datos$estadisticas %>%
kbl(
align = c('l', 'r'),
escape = FALSE,
col.names = c("Métrica", "Valor")
) %>%
kable_styling(
bootstrap_options = c("striped", "hover"),
full_width = TRUE,
font_size = 13
) %>%
row_spec(0, background = "#00e5ff", color = "#000", bold = TRUE, font_size = 14) %>%
row_spec(1, background = "#12161f", color = "#00e5ff", bold = TRUE, font_size = 14) %>%
row_spec(2:8, background = "#0d1117", color = "#e0e6ed") %>%
column_spec(1, width = "14em", bold = TRUE, color = "#e0e6ed") %>%
column_spec(2, width = "10em", color = "#00e5ff", bold = TRUE)
print(tabla_stats)
cat('\n\n</div>\n\n')
cat('<div class="table-container">\n\n')
cat('<p class="section-title"> Top 10 Países</p>\n\n')
tabla_top10_data <- datos$top10 %>%
mutate(
Pct_Display_Colored = cell_spec(
Pct_Display,
"html",
color = Pct_Color,
bold = TRUE
)
) %>%
select(`#` = Ranking, País, Valor, `% vs Media` = Pct_Display_Colored)
tabla_top10 <- tabla_top10_data %>%
kbl(
align = c('c', 'l', 'r', 'c'),
escape = FALSE
) %>%
kable_styling(
bootstrap_options = c("striped", "hover"),
full_width = TRUE,
font_size = 13
) %>%
row_spec(0, background = "#0084ff", color = "#000", bold = TRUE, font_size = 14) %>%
row_spec(1:10, background = "#0d1117", color = "#e0e6ed") %>%
column_spec(1, width = "3em", bold = TRUE, color = "#000", background = "#00e5ff") %>%
column_spec(2, width = "13em", bold = TRUE) %>%
column_spec(3, width = "9em", color = "#00e5ff", bold = TRUE)
print(tabla_top10)
cat('\n\n</div>\n\n')
cat('</div>\n\n')
}Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 17045.36 |
| Mediana | 6705.15 |
| Desv. Est. | 22688.73 |
| Q1 | 2610.30 |
| Q3 | 21062.53 |
| Mínimo | 250.63 |
| Máximo | 109269.52 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Norway | 109269.52 | +541.1% |
| 2 | Ireland | 105234.51 | +517.4% |
| 3 | Switzerland | 94394.51 | +453.8% |
| 4 | Qatar | 88701.46 | +420.4% |
| 5 | United States | 77860.91 | +356.8% |
| 6 | Iceland | 75121.02 | +340.7% |
| 7 | Denmark | 68091.32 | +299.5% |
| 8 | Australia | 64997.01 | +281.3% |
| 9 | Netherlands | 59123.32 | +246.9% |
| 10 | Sweden | 55296.94 | +224.4% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140 |
| Media | 49640844 |
| Mediana | 10435607 |
| Desv. Est. | 173452511 |
| Q1 | 2949316 |
| Q3 | 33230724 |
| Mínimo | 33755 |
| Máximo | 1425423212 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | India | 1425423212 | +2771.5% |
| 2 | China | 1412175000 | +2744.8% |
| 3 | United States | 334017321 | +572.9% |
| 4 | Indonesia | 278830529 | +461.7% |
| 5 | Pakistan | 243700667 | +390.9% |
| 6 | Brazil | 210306415 | +323.7% |
| 7 | Bangladesh | 169384897 | +241.2% |
| 8 | Russian Federation | 144236933 | +190.6% |
| 9 | Mexico | 128613117 | +159.1% |
| 10 | Japan | 125124989 | +152.1% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 73.46 |
| Mediana | 74.35 |
| Desv. Est. | 6.73 |
| Q1 | 68.16 |
| Q3 | 78.05 |
| Mínimo | 56.81 |
| Máximo | 85.71 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | San Marino | 85.70800 | +16.7% |
| 2 | Japan | 83.99634 | +14.3% |
| 3 | Switzerland | 83.60488 | +13.8% |
| 4 | Australia | 83.20000 | +13.3% |
| 5 | Spain | 83.13415 | +13.2% |
| 6 | Sweden | 83.05854 | +13.1% |
| 7 | Israel | 82.70000 | +12.6% |
| 8 | Italy | 82.70000 | +12.6% |
| 9 | Korea, Rep. | 82.68049 | +12.6% |
| 10 | Ireland | 82.50976 | +12.3% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 88.23 |
| Mediana | 100.00 |
| Desv. Est. | 22.08 |
| Q1 | 90.95 |
| Q3 | 100.00 |
| Mínimo | 10.30 |
| Máximo | 100.00 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Albania | 100 | +13.3% |
| 2 | Algeria | 100 | +13.3% |
| 3 | Antigua and Barbuda | 100 | +13.3% |
| 4 | Argentina | 100 | +13.3% |
| 5 | Armenia | 100 | +13.3% |
| 6 | Australia | 100 | +13.3% |
| 7 | Austria | 100 | +13.3% |
| 8 | Azerbaijan | 100 | +13.3% |
| 9 | Bahamas, The | 100 | +13.3% |
| 10 | Belarus | 100 | +13.3% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 30.62 |
| Mediana | 30.66 |
| Desv. Est. | 20.77 |
| Q1 | 11.82 |
| Q3 | 46.22 |
| Mínimo | 0.00 |
| Máximo | 90.09 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Solomon Islands | 90.08610 | +194.2% |
| 2 | Finland | 73.72650 | +140.8% |
| 3 | Bhutan | 71.55218 | +133.7% |
| 4 | Guinea-Bissau | 69.81259 | +128% |
| 5 | Sweden | 68.69967 | +124.4% |
| 6 | Japan | 68.40878 | +123.4% |
| 7 | Korea, Rep. | 64.21107 | +109.7% |
| 8 | Congo, Rep. | 64.17570 | +109.6% |
| 9 | Fiji | 63.12972 | +106.2% |
| 10 | Timor-Leste | 61.75521 | +101.7% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 116.43 |
| Mediana | 116.33 |
| Desv. Est. | 31.30 |
| Q1 | 101.07 |
| Q3 | 135.29 |
| Mínimo | 39.71 |
| Máximo | 207.28 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Montenegro | 207.278 | +78% |
| 2 | Antigua and Barbuda | 200.541 | +72.2% |
| 3 | El Salvador | 183.249 | +57.4% |
| 4 | Botswana | 178.205 | +53.1% |
| 5 | Thailand | 176.223 | +51.4% |
| 6 | Japan | 168.603 | +44.8% |
| 7 | Russian Federation | 168.476 | +44.7% |
| 8 | Kuwait | 168.350 | +44.6% |
| 9 | Mauritius | 164.309 | +41.1% |
| 10 | Qatar | 162.249 | +39.4% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 4.53 |
| Mediana | 4.52 |
| Desv. Est. | 4.25 |
| Q1 | 2.69 |
| Q3 | 6.30 |
| Mínimo | -20.54 |
| Máximo | 19.79 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Fiji | 19.792727 | +336.9% |
| 2 | Cabo Verde | 15.843676 | +249.8% |
| 3 | Maldives | 13.826090 | +205.2% |
| 4 | Armenia | 12.600000 | +178.1% |
| 5 | Saudi Arabia | 12.000587 | +164.9% |
| 6 | Niger | 11.900000 | +162.7% |
| 7 | Georgia | 10.958532 | +141.9% |
| 8 | Bahamas, The | 10.877455 | +140.1% |
| 9 | Panama | 10.769666 | +137.7% |
| 10 | Belize | 9.652978 | +113.1% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 17.15 |
| Mediana | 11.40 |
| Desv. Est. | 16.10 |
| Q1 | 4.05 |
| Q3 | 24.77 |
| Mínimo | 1.40 |
| Máximo | 68.30 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Niger | 68.3 | +298.3% |
| 2 | Guinea | 63.1 | +267.9% |
| 3 | Mali | 59.0 | +244% |
| 4 | Sierra Leone | 58.0 | +238.2% |
| 5 | Lesotho | 57.6 | +235.9% |
| 6 | Pakistan | 51.8 | +202% |
| 7 | Cote d’Ivoire | 47.9 | +179.3% |
| 8 | Benin | 47.7 | +178.1% |
| 9 | Mozambique | 46.5 | +171.1% |
| 10 | Burkina Faso | 46.1 | +168.8% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 4.17 |
| Mediana | 2.55 |
| Desv. Est. | 11.07 |
| Q1 | 1.37 |
| Q3 | 4.72 |
| Mínimo | -8.42 |
| Máximo | 126.08 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Malta | 126.08409 | +2923.6% |
| 2 | Antigua and Barbuda | 16.78323 | +302.5% |
| 3 | Mozambique | 16.00429 | +283.8% |
| 4 | Mauritania | 14.66442 | +251.7% |
| 5 | Mongolia | 14.60531 | +250.2% |
| 6 | Montenegro | 14.00620 | +235.9% |
| 7 | Uruguay | 12.48041 | +199.3% |
| 8 | Maldives | 11.84548 | +184.1% |
| 9 | Senegal | 10.54112 | +152.8% |
| 10 | Gambia, The | 10.49959 | +151.8% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 6.96 |
| Mediana | 7.09 |
| Desv. Est. | 2.77 |
| Q1 | 4.48 |
| Q3 | 8.89 |
| Mínimo | 2.18 |
| Máximo | 16.50 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | United States | 16.49614 | +137% |
| 2 | Timor-Leste | 14.32455 | +105.8% |
| 3 | Lesotho | 12.65128 | +81.8% |
| 4 | Germany | 12.60513 | +81.1% |
| 5 | France | 11.88190 | +70.7% |
| 6 | Marshall Islands | 11.73604 | +68.6% |
| 7 | Switzerland | 11.70653 | +68.2% |
| 8 | Japan | 11.42184 | +64.1% |
| 9 | Austria | 11.15729 | +60.3% |
| 10 | United Kingdom | 11.05088 | +58.8% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 70.47 |
| Mediana | 78.71 |
| Desv. Est. | 24.39 |
| Q1 | 55.78 |
| Q3 | 89.23 |
| Mínimo | 11.00 |
| Máximo | 100.00 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Saudi Arabia | 100.0000 | +41.9% |
| 2 | Iceland | 99.8082 | +41.6% |
| 3 | Kuwait | 99.7237 | +41.5% |
| 4 | Qatar | 99.6528 | +41.4% |
| 5 | Norway | 99.0000 | +40.5% |
| 6 | Denmark | 97.8601 | +38.9% |
| 7 | Malaysia | 97.3986 | +38.2% |
| 8 | Korea, Rep. | 97.1686 | +37.9% |
| 9 | Australia | 97.0424 | +37.7% |
| 10 | Ireland | 96.6206 | +37.1% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 51.02 |
| Mediana | 46.08 |
| Desv. Est. | 26.23 |
| Q1 | 30.83 |
| Q3 | 64.03 |
| Mínimo | 15.06 |
| Máximo | 173.02 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | San Marino | 173.02372 | +239.1% |
| 2 | Djibouti | 143.03467 | +180.4% |
| 3 | Malta | 115.00492 | +125.4% |
| 4 | Slovak Republic | 104.93886 | +105.7% |
| 5 | Cyprus | 102.01066 | +99.9% |
| 6 | Belgium | 96.69985 | +89.5% |
| 7 | Lesotho | 95.86760 | +87.9% |
| 8 | Ireland | 95.44505 | +87.1% |
| 9 | Hungary | 94.30488 | +84.8% |
| 10 | North Macedonia | 93.36196 | +83% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 45.73 |
| Mediana | 41.40 |
| Desv. Est. | 29.28 |
| Q1 | 26.03 |
| Q3 | 55.53 |
| Mínimo | 4.97 |
| Máximo | 197.41 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | San Marino | 197.41235 | +331.7% |
| 2 | Djibouti | 159.25074 | +248.2% |
| 3 | Ireland | 136.68444 | +198.9% |
| 4 | Malta | 128.41046 | +180.8% |
| 5 | Cyprus | 105.62177 | +131% |
| 6 | Slovak Republic | 98.99011 | +116.5% |
| 7 | Netherlands | 96.44362 | +110.9% |
| 8 | Belgium | 95.23960 | +108.3% |
| 9 | Slovenia | 93.98266 | +105.5% |
| 10 | Viet Nam | 93.42013 | +104.3% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 16.23 |
| Mediana | 12.41 |
| Desv. Est. | 14.09 |
| Q1 | 5.13 |
| Q3 | 24.06 |
| Mínimo | 0.13 |
| Máximo | 60.78 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Bangladesh | 60.78382 | +274.5% |
| 2 | Denmark | 59.00000 | +263.5% |
| 3 | Moldova | 56.75182 | +249.7% |
| 4 | India | 51.80548 | +219.2% |
| 5 | Burundi | 50.37027 | +210.4% |
| 6 | Rwanda | 50.20054 | +209.3% |
| 7 | Togo | 48.72219 | +200.2% |
| 8 | Hungary | 45.55853 | +180.7% |
| 9 | Gambia, The | 43.47826 | +167.9% |
| 10 | Pakistan | 39.21492 | +141.6% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 1.13 |
| Mediana | 1.00 |
| Desv. Est. | 1.38 |
| Q1 | 0.29 |
| Q3 | 1.99 |
| Mínimo | -3.17 |
| Máximo | 5.91 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Qatar | 5.907018 | +422.7% |
| 2 | Kuwait | 5.113181 | +352.5% |
| 3 | Oman | 4.980137 | +340.7% |
| 4 | Saudi Arabia | 4.418920 | +291.1% |
| 5 | Niger | 3.251706 | +187.8% |
| 6 | Congo, Dem. Rep. | 3.223402 | +185.3% |
| 7 | Angola | 3.143026 | +178.1% |
| 8 | Mali | 3.009426 | +166.3% |
| 9 | Uganda | 3.007595 | +166.2% |
| 10 | Tanzania | 2.950467 | +161.1% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 27.00 |
| Mediana | 25.26 |
| Desv. Est. | 11.60 |
| Q1 | 19.96 |
| Q3 | 31.75 |
| Mínimo | 2.39 |
| Máximo | 65.77 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Kuwait | 65.76633 | +143.6% |
| 2 | Qatar | 65.34890 | +142% |
| 3 | Iraq | 65.27212 | +141.7% |
| 4 | Oman | 59.48521 | +120.3% |
| 5 | Azerbaijan | 56.14674 | +108% |
| 6 | Timor-Leste | 54.51234 | +101.9% |
| 7 | Saudi Arabia | 53.12377 | +96.8% |
| 8 | Congo, Rep. | 49.24555 | +82.4% |
| 9 | Norway | 49.12890 | +82% |
| 10 | Congo, Dem. Rep. | 47.77963 | +77% |
Estadísticas Globales
| Métrica | Valor |
|---|---|
| Total Países | 140.00 |
| Media | 5.87 |
| Mediana | 2.18 |
| Desv. Est. | 9.39 |
| Q1 | 0.46 |
| Q3 | 6.74 |
| Mínimo | 0.01 |
| Máximo | 53.22 |
Top 10 Países
| # | País | Valor | % vs Media |
|---|---|---|---|
| 1 | Nepal | 53.22215 | +806.7% |
| 2 | Tajikistan | 49.89531 | +750% |
| 3 | Tonga | 41.94160 | +614.5% |
| 4 | Samoa | 33.61166 | +472.6% |
| 5 | Lebanon | 30.65552 | +422.2% |
| 6 | Honduras | 27.00110 | +360% |
| 7 | Kyrgyz Republic | 26.57756 | +352.8% |
| 8 | El Salvador | 24.63437 | +319.7% |
| 9 | Gambia, The | 22.76212 | +287.8% |
| 10 | Lesotho | 22.61587 | +285.3% |
preparar_top15 <- function(data, variable, nombre_var) {
resultado <- data %>%
filter(!is.na(!!sym(variable)) & !!sym(variable) > 0) %>% # Filtra NA y valores <= 0
arrange(desc(!!sym(variable))) %>%
slice_head(n = 15) %>%
arrange(!!sym(variable)) %>% # Ordenar de menor a mayor para visualización
mutate(
Pais_label = Pais,
Valor = !!sym(variable),
tooltip = paste0(
"<b style='color:#00e5ff;'>", Pais, "</b><br>",
"<span style='color:#00e676;'><b>", nombre_var, ":</b></span><br>",
"<b style='color:#ffd600;'>", format(round(Valor, 2), big.mark = ",", scientific = FALSE), "</b>"
)
) %>%
select(Pais_label, Valor, tooltip)
return(resultado)
}
vars_config <- list(
list(var = "PIB_per", nombre = "PIB per cápita (US$)", color = "#00e676"),
list(var = "Crecimiento PIB", nombre = "Crecimiento PIB (% anual)", color = "#0084ff"),
list(var = "Inversion extranjera", nombre = "Inversión Extranjera Directa (% PIB)", color = "#ffd600"),
list(var = "Remesas", nombre = "Remesas recibidas (% PIB)", color = "#a259ff"),
list(var = "Industria", nombre = "Industria (% PIB)", color = "#ff6b00"),
list(var = "Exportaciones", nombre = "Exportaciones (% PIB)", color = "#00e5ff"),
list(var = "Importaciones", nombre = "Importaciones (% PIB)", color = "#ff1744")
)
datasets <- lapply(seq_along(vars_config), function(i) {
config <- vars_config[[i]]
preparar_top15(Base_2022, config$var, config$nombre)
})
p <- plot_ly()
for (i in seq_along(vars_config)) {
config <- vars_config[[i]]
if(nrow(datasets[[i]]) > 0) {
p <- p %>%
add_trace(
x = datasets[[i]]$Valor,
y = datasets[[i]]$Pais_label,
type = 'bar',
orientation = 'h',
marker = list(
color = config$color,
line = list(color = '#ffffff', width = 1.5)
),
text = format(round(datasets[[i]]$Valor, 2), big.mark = ",", scientific = FALSE),
textposition = 'outside',
textfont = list(color = '#00e5ff', size = 13, family = "Arial"),
customdata = datasets[[i]]$tooltip,
hovertemplate = "%{customdata}<extra></extra>",
name = config$nombre,
visible = (i == 1),
showlegend = FALSE
)
}
}
p %>%
layout(
title = list(
text = paste0(
"<b style='color:#00e5ff; font-size:24px;'>Top 15 Países - ",
vars_config[[1]]$nombre,
"</b><br>",
"<span style='color:#8b92a0; font-size:14px;'>Año 2022 | Selecciona una variable para cambiar</span>"
),
x = 0.5,
xanchor = 'center',
y = 0.95
),
xaxis = list(
title = paste0("<b style='font-size:16px;'>", vars_config[[1]]$nombre, "</b>"),
gridcolor = '#12161f',
showgrid = TRUE,
zeroline = TRUE,
zerolinewidth = 2,
zerolinecolor = "rgba(0, 229, 255, 0.5)",
tickfont = list(color = '#8b92a0', size = 13),
titlefont = list(color = '#e0e6ed', size = 16),
range = c(0, max(datasets[[1]]$Valor) * 1.15) # Rango dinámico con margen
),
yaxis = list(
title = "<b style='font-size:16px;'>País</b>",
tickfont = list(color = '#e0e6ed', size = 13),
titlefont = list(color = '#e0e6ed', size = 16),
categoryorder = "array",
categoryarray = rev(datasets[[1]]$Pais_label),
automargin = TRUE # Ajuste automático de márgenes
),
plot_bgcolor = '#000000',
paper_bgcolor = '#0a0e1a',
font = list(family = "Arial, sans-serif", color = '#e0e6ed', size = 13),
# MÁRGENES OPTIMIZADOS PARA ANCHO MÁXIMO
margin = list(l = 180, r = 50, b = 80, t = 120), # Margen derecho muy reducido
hovermode = 'closest',
# ========== BOTONES INTERACTIVOS MEJOR POSICIONADOS ==========
updatemenus = list(
list(
buttons = lapply(seq_along(vars_config), function(i) {
config <- vars_config[[i]]
# Crear array de visibilidad
visible <- rep(FALSE, length(vars_config))
visible[i] <- TRUE
list(
label = strsplit(config$nombre, " \\(")[[1]][1],
method = "update",
args = list(
list(visible = visible),
list(
title = paste0(
"<b style='color:#00e5ff; font-size:24px;'>Top 15 Países - ",
config$nombre,
"</b><br>",
"<span style='color:#8b92a0; font-size:14px;'>Año 2022 | Selecciona una variable para cambiar</span>"
),
"xaxis.title" = paste0("<b style='font-size:16px;'>", config$nombre, "</b>"),
"xaxis.range" = c(0, max(datasets[[i]]$Valor) * 1.15),
"yaxis.categoryarray" = rev(datasets[[i]]$Pais_label)
)
)
)
}),
direction = "down",
pad = list(r = 10, t = 10),
showactive = TRUE,
x = 0.02, # Más a la izquierda
xanchor = "left",
y = 1.02, # Justo debajo del título
yanchor = "bottom",
bgcolor = "rgba(0, 229, 255, 0.15)",
bordercolor = "#00e5ff",
borderwidth = 2,
font = list(size = 12, color = "#00e5ff", family = "Arial")
)
),
# ANOTACIONES MEJORADAS
annotations = list(
list(
x = 1.02, # Justo fuera del área del gráfico a la derecha
y = 0.5,
xref = "paper",
yref = "paper",
text = "<span style='color:#8b92a0; font-size:11px;'>💡<br>Click en los<br>botones para<br>cambiar variable</span>",
showarrow = FALSE,
xanchor = "left",
yanchor = "middle",
bgcolor = "rgba(10, 14, 26, 0.8)",
bordercolor = "#00e5ff",
borderwidth = 1,
borderpad = 8
)
)
) %>%
config(
responsive = TRUE,
displayModeBar = TRUE,
displaylogo = FALSE,
modeBarButtonsToRemove = list('lasso2d', 'select2d'),
toImageButtonOptions = list(
format = "png",
filename = "top15_economia_2022",
width = 1600,
height = 900
)
)# Asignar continentes
asignar_continentes <- function(data) {
continentes_map <- c(
"Argentina" = "Americas", "Bahamas, The" = "Americas", "Barbados" = "Americas",
"Belize" = "Americas", "Bolivia" = "Americas", "Brazil" = "Americas",
"Canada" = "Americas", "Chile" = "Americas", "Colombia" = "Americas",
"Costa Rica" = "Americas", "Cuba" = "Americas", "Dominica" = "Americas",
"Dominican Republic" = "Americas", "Ecuador" = "Americas", "El Salvador" = "Americas",
"Grenada" = "Americas", "Guatemala" = "Americas", "Guyana" = "Americas",
"Haiti" = "Americas", "Honduras" = "Americas", "Jamaica" = "Americas",
"Mexico" = "Americas", "Nicaragua" = "Americas", "Panama" = "Americas",
"Paraguay" = "Americas", "Peru" = "Americas", "St. Kitts and Nevis" = "Americas",
"St. Lucia" = "Americas", "St. Vincent and the Grenadines" = "Americas",
"Suriname" = "Americas", "Trinidad and Tobago" = "Americas", "United States" = "Americas",
"Uruguay" = "Americas", "Venezuela, RB" = "Americas", "Antigua and Barbuda" = "Americas",
"Albania" = "Europe", "Austria" = "Europe", "Belarus" = "Europe",
"Belgium" = "Europe", "Bosnia and Herzegovina" = "Europe", "Bulgaria" = "Europe",
"Croatia" = "Europe", "Cyprus" = "Europe", "Czech Republic" = "Europe",
"Czechia" = "Europe", "Denmark" = "Europe", "Estonia" = "Europe",
"Finland" = "Europe", "France" = "Europe", "Germany" = "Europe",
"Greece" = "Europe", "Hungary" = "Europe", "Iceland" = "Europe",
"Ireland" = "Europe", "Italy" = "Europe", "Kosovo" = "Europe",
"Latvia" = "Europe", "Lithuania" = "Europe", "Luxembourg" = "Europe",
"Malta" = "Europe", "Montenegro" = "Europe", "Netherlands" = "Europe",
"North Macedonia" = "Europe", "Norway" = "Europe", "Poland" = "Europe",
"Portugal" = "Europe", "Russian Federation" = "Europe", "Serbia" = "Europe",
"Slovak Republic" = "Europe", "Slovakia" = "Europe", "Slovenia" = "Europe",
"Spain" = "Europe", "Sweden" = "Europe", "Switzerland" = "Europe",
"Turkey" = "Europe", "Turkiye" = "Europe", "Ukraine" = "Europe",
"United Kingdom" = "Europe", "Armenia" = "Europe", "Azerbaijan" = "Europe",
"Georgia" = "Europe", "Moldova" = "Europe", "Romania" = "Europe",
"San Marino" = "Europe",
"Afghanistan" = "Asia", "Bahrain" = "Asia", "Bangladesh" = "Asia",
"Bhutan" = "Asia", "Brunei Darussalam" = "Asia", "Cambodia" = "Asia",
"China" = "Asia", "Hong Kong SAR, China" = "Asia", "India" = "Asia",
"Indonesia" = "Asia", "Iran, Islamic Rep." = "Asia", "Iraq" = "Asia",
"Israel" = "Asia", "Japan" = "Asia", "Jordan" = "Asia",
"Kazakhstan" = "Asia", "Korea, Dem. People's rep." = "Asia", "Korea, Rep." = "Asia",
"Kuwait" = "Asia", "Kyrgyz Republic" = "Asia", "Lao PDR" = "Asia",
"Lebanon" = "Asia", "Macao SAR, China" = "Asia", "Malaysia" = "Asia",
"Maldives" = "Asia", "Mongolia" = "Asia", "Myanmar" = "Asia",
"Nepal" = "Asia", "Oman" = "Asia", "Pakistan" = "Asia",
"Philippines" = "Asia", "Qatar" = "Asia", "Saudi Arabia" = "Asia",
"Singapore" = "Asia", "Sri Lanka" = "Asia", "Syrian Arab Republic" = "Asia",
"Taiwan" = "Asia", "Tajikistan" = "Asia", "Thailand" = "Asia",
"Timor-Leste" = "Asia", "Turkmenistan" = "Asia", "United Arab Emirates" = "Asia",
"Uzbekistan" = "Asia", "Vietnam" = "Asia", "Viet Nam" = "Asia",
"West Bank and Gaza" = "Asia", "Yemen, Rep." = "Asia",
"Algeria" = "Africa", "Angola" = "Africa", "Benin" = "Africa",
"Botswana" = "Africa", "Burkina Faso" = "Africa", "Burundi" = "Africa",
"Cabo Verde" = "Africa", "Cameroon" = "Africa", "Central African Republic" = "Africa",
"Chad" = "Africa", "Comoros" = "Africa", "Congo, Dem. Rep." = "Africa",
"Congo, Rep." = "Africa", "Cote d'Ivoire" = "Africa", "Djibouti" = "Africa",
"Egypt, Arab Rep." = "Africa", "Equatorial Guinea" = "Africa", "Eritrea" = "Africa",
"Eswatini" = "Africa", "Ethiopia" = "Africa", "Gabon" = "Africa",
"Gambia, The" = "Africa", "Ghana" = "Africa", "Guinea" = "Africa",
"Guinea-Bissau" = "Africa", "Kenya" = "Africa", "Lesotho" = "Africa",
"Liberia" = "Africa", "Libya" = "Africa", "Madagascar" = "Africa",
"Malawi" = "Africa", "Mali" = "Africa", "Mauritania" = "Africa",
"Mauritius" = "Africa", "Morocco" = "Africa", "Mozambique" = "Africa",
"Namibia" = "Africa", "Niger" = "Africa", "Nigeria" = "Africa",
"Rwanda" = "Africa", "Senegal" = "Africa", "Sierra Leone" = "Africa",
"Somalia" = "Africa", "South Africa" = "Africa", "South Sudan" = "Africa",
"Sudan" = "Africa", "Tanzania" = "Africa", "Togo" = "Africa",
"Tunisia" = "Africa", "Uganda" = "Africa", "Zambia" = "Africa",
"Zimbabwe" = "Africa",
"Australia" = "Oceania", "Fiji" = "Oceania", "Kiribati" = "Oceania",
"Marshall Islands" = "Oceania", "Micronesia, Fed. Sts." = "Oceania",
"New Zealand" = "Oceania", "Palau" = "Oceania", "Samoa" = "Oceania",
"Solomon Islands" = "Oceania", "Tonga" = "Oceania", "Vanuatu" = "Oceania"
)
data %>%
mutate(Continente = ifelse(Pais %in% names(continentes_map),
continentes_map[Pais], NA))
}
# Preparar datos - SOLO VARIABLES DE SALUD
datos_ev_mi <- Base_2022 %>%
asignar_continentes() %>%
filter(!is.na(`Esperanza vida`) &
!is.na(`Mortalidad infantil`) &
!is.na(`Gasto salud`) &
!is.na(Continente)) %>%
select(Pais, Continente, `Esperanza vida`, `Mortalidad infantil`, `Gasto salud`) %>%
mutate(
tooltip = paste0(
"<b style='font-size:14px; color:#00e5ff;'>", Pais, "</b><br>",
"<span style='color:#a259ff; font-size:11px;'>", Continente, "</span><br><br>",
"<b style='color:#e0e6ed; font-size:11px;'>INDICADORES DE SALUD:</b><br>",
"├─ Esperanza de vida: <b style='color:#00e676;'>",
round(`Esperanza vida`, 1), " años</b><br>",
"├─ Mortalidad infantil: <b style='color:#ff1744;'>",
round(`Mortalidad infantil`, 1), "/1,000</b><br>",
"└─ Gasto en salud: <b style='color:#ffd600;'>",
round(`Gasto salud`, 2), "% PIB</b>"
)
)
# Crear gráfico scatter optimizado al máximo
p <- plot_ly(
data = datos_ev_mi,
x = ~`Esperanza vida`,
y = ~`Mortalidad infantil`,
color = ~Continente,
colors = c(
"Americas" = "green",
"Europe" = "#0084ff",
"Asia" = "#ffd600",
"Africa" = "#ff1744",
"Oceania" = "#a259ff"
),
type = 'scatter',
mode = 'markers',
customdata = ~tooltip,
hovertemplate = "%{customdata}<extra></extra>",
marker = list(
size = 14, # Marcadores aún más grandes
opacity = 0.9,
line = list(color = '#ffffff', width = 2)
),
showlegend = TRUE
) %>%
layout(
title = list(
text = "<b style='color:#00e5ff; font-size:24px;'>Salud Poblacional: Esperanza de Vida vs Mortalidad Infantil</b><br>
<span style='color:#8b92a0; font-size:14px;'>Año 2022 | Relación inversa: mejor salud = mayor EV y menor MI</span>",
x = 0.5,
xanchor = 'center',
y = 0.95
),
xaxis = list(
title = "<b style='font-size:16px;'>Esperanza de vida al nacer (años)</b>",
gridcolor = '#12161f',
showgrid = TRUE,
zeroline = FALSE,
range = c(40, 90), # Rango más amplio
tickfont = list(color = '#8b92a0', size = 13),
titlefont = list(color = '#e0e6ed', size = 16)
),
yaxis = list(
title = "<b style='font-size:16px;'>Mortalidad infantil (por 1,000 nacidos vivos)</b>",
gridcolor = '#12161f',
showgrid = TRUE,
zeroline = FALSE,
range = c(0, 110),
tickfont = list(color = '#8b92a0', size = 13),
titlefont = list(color = '#e0e6ed', size = 16)
),
plot_bgcolor = '#000000',
paper_bgcolor = '#0a0e1a',
font = list(family = "Arial, sans-serif", color = '#e0e6ed', size = 13),
legend = list(
title = list(text = "<b style='font-size:14px;'>Continente</b>", font = list(size = 14, color = "#00e5ff")),
bgcolor = 'rgba(10,14,26,0.95)',
bordercolor = '#00e5ff',
borderwidth = 2,
x = 0.99, # Más pegado al borde derecho
y = 0.99, # Más pegado al borde superior
xanchor = "right",
yanchor = "top",
font = list(size = 13, color = "#e0e6ed")
),
# MÁRGENES MUY COMPACTOS
margin = list(l = 80, r = 120, b = 60, t = 100), # Margen derecho reducido
hovermode = 'closest',
# ZONAS DE INTERPRETACIÓN MÁS VISIBLES
shapes = list(
# Zona ÓPTIMA
list(
type = "rect",
x0 = 75, x1 = 90,
y0 = 0, y1 = 15,
xref = "x", yref = "y",
fillcolor = "rgba(0, 230, 118, 0.15)",
line = list(color = "rgba(0, 230, 118, 0.7)", width = 2.5, dash = "dot"),
layer = "below"
),
# Zona CRÍTICA
list(
type = "rect",
x0 = 40, x1 = 65,
y0 = 40, y1 = 110,
xref = "x", yref = "y",
fillcolor = "rgba(255, 23, 68, 0.15)",
line = list(color = "rgba(255, 23, 68, 0.7)", width = 2.5, dash = "dot"),
layer = "below"
)
),
annotations = list(
# Anotación ZONA ÓPTIMA
list(
x = 82.5,
y = 25, # Mover más arriba para evitar superposición
text = "<b style='color:#00e676; font-size:13px;'>✓ ZONA ÓPTIMA</b><br><span style='color:#00e676; font-size:11px;'>Alta EV + Baja MI</span>",
showarrow = FALSE,
bgcolor = "rgba(0, 230, 118, 0.25)",
bordercolor = "#00e676",
borderwidth = 2,
borderpad = 8,
font = list(size = 11),
xanchor = "center"
),
# Anotación ZONA CRÍTICA
list(
x = 52.5,
y = 95, # Mover más abajo para evitar superposición
text = "<b style='color:#ff1744; font-size:13px;'>⚠ ZONA CRÍTICA</b><br><span style='color:#ff1744; font-size:11px;'>Baja EV + Alta MI</span>",
showarrow = FALSE,
bgcolor = "rgba(255, 23, 68, 0.25)",
bordercolor = "#ff1744",
borderwidth = 2,
borderpad = 8,
font = list(size = 11),
xanchor = "center"
),
# Anotación explicativa
list(
x = 0.02,
y = -0.12,
text = "<span style='color:#8b92a0; font-size:11px;'>Cada punto representa un país | Arrastra para zoom | Doble click para resetear</span>",
showarrow = FALSE,
xref = "paper",
yref = "paper",
xanchor = "left"
),
# Anotación de correlación (valor añadido)
list(
x = 0.98,
y = -0.12,
text = "<span style='color:#8b92a0; font-size:11px;'>Correlación inversa fuerte: r = ~ -0.85</span>",
showarrow = FALSE,
xref = "paper",
yref = "paper",
xanchor = "right"
)
)
) %>%
config(
responsive = TRUE,
displayModeBar = TRUE,
displaylogo = FALSE,
modeBarButtonsToRemove = list('lasso2d', 'select2d'),
toImageButtonOptions = list(
format = "png",
filename = "salud_poblacional_2022",
width = 1800, # Mayor resolución
height = 1000
)
)
p# Instalar ggtext si es necesario
if (!require(ggtext)) install.packages("ggtext")
library(ggtext)
library(ggplot2)
library(plotly)
library(dplyr)
library(ggrepel)
datos_scatter_gg <- Base_2022 %>%
asignar_continentes() %>%
filter(
!is.na(`Acceso electricidad`) &
!is.na(`Uso internet`) &
!is.na(`Suscripciones movil`) &
!is.na(Continente) &
Continente != "Otros"
) %>%
mutate(
Electricidad = `Acceso electricidad`,
Internet = `Uso internet`,
Movil = `Suscripciones movil`,
Continente = factor(Continente,
levels = c("Africa", "Americas", "Asia", "Europe", "Oceania"))
) %>%
arrange(Continente)
p_gg <- ggplot(datos_scatter_gg, aes(x = Electricidad, y = Internet)) +
geom_abline(
intercept = 0,
slope = 1,
linetype = "dashed",
color = "#00e5ff",
linewidth = 1,
alpha = 0.3
) +
geom_point(
aes(
fill = Continente,
size = Movil,
text = paste0(
"<b style='font-size:14px;'>", Pais, "</b><br>",
"<span style='color:#a259ff; font-size:11px;'>", Continente, "</span><br><br>",
"<b style='color:#ffd600;'> INDICADORES</b><br>",
"├─ 🔌 Electricidad: <b style='color:#00e676;'>",
round(Electricidad, 1), "%</b><br>",
"├─ 🌐 Internet: <b style='color:#00e5ff;'>",
round(Internet, 1), "%</b><br>",
"└─ 📱 Móviles: <b style='color:#ffd600;'>",
round(Movil, 1), "/100 hab.</b>"
)
),
alpha = 0.78,
shape = 19,
color = NA
) +
scale_size_continuous(
name = "Suscripciones Móviles\n(por 100 hab.)",
range = c(2, 10),
breaks = c(20, 50, 100, 150),
labels = c("20", "50", "100", "150+")
) +
geom_text_repel(
aes(label = Pais),
size = 2.8,
color = "#e0e6ed",
max.overlaps = 20,
segment.color = "#00e5ff",
segment.alpha = 0.3,
segment.size = 0.3
) +
facet_wrap(~Continente, ncol = 3) +
scale_fill_manual(
name = "Continente",
values = c(
"Africa" = "#ff1744",
"Americas" = "#00e676",
"Asia" = "#ffd600",
"Europe" = "#0084ff",
"Oceania" = "#a259ff"
)
) +
scale_x_continuous(limits = c(0, 105), breaks = seq(0, 100, 20)) +
scale_y_continuous(limits = c(0, 105), breaks = seq(0, 100, 20)) +
labs(
title = "Infraestructura Digital: Análisis Multidimensional por Región",
subtitle = "Año 2022 | Tamaño de burbuja = Suscripciones Móviles (por 100 hab)",
x = "Acceso a Electricidad (% población)",
y = "Uso de Internet (% población)"
) +
theme_minimal(base_size = 11) +
theme(
plot.background = element_rect(fill = "#000000", color = NA),
panel.background = element_rect(fill = "#0a0e1a", color = NA),
panel.grid.major = element_line(color = "#12161f", linewidth = 0.3),
panel.grid.minor = element_line(color = "#12161f", linewidth = 0.2),
plot.title = element_text(
color = "#00e5ff",
face = "bold",
size = 16,
hjust = 0.5,
margin = margin(b = 8)
),
plot.subtitle = element_text(
color = "#8b92a0",
size = 11,
hjust = 0.5,
margin = margin(b = 15),
lineheight = 1.2,
face = "italic"
),
axis.title = element_text(
color = "#e0e6ed",
face = "bold",
size = 11
),
axis.text = element_text(color = "#8b92a0", size = 10),
axis.line = element_line(color = "#00e5ff", linewidth = 0.4),
strip.text = element_text(
color = "#00e5ff",
face = "bold",
size = 12,
margin = margin(b = 8)
),
strip.background = element_rect(
fill = "#1a1a3e",
color = "#00e5ff",
linewidth = 1.2
),
# LEYENDAS - AMBAS ACTIVAS
legend.background = element_rect(
fill = "#0a0e1a",
color = "#00e5ff",
linewidth = 1.2
),
legend.text = element_text(color = "#e0e6ed", size = 11),
legend.title = element_text(color = "#00e5ff", face = "bold", size = 12),
legend.key = element_rect(fill = "#0a0e1a", color = NA),
legend.key.size = unit(0.8, "cm"),
legend.position = "right",
legend.box = "vertical",
legend.spacing.y = unit(0.5, "cm"),
legend.margin = margin(10, 10, 10, 10),
plot.margin = margin(15, 15, 15, 15)
)
# Convertir a plotly y AJUSTAR LEYENDAS SEPARADAMENTE
plotly_plot <- ggplotly(p_gg, tooltip = "text") %>%
layout(
# Leyenda de continentes (arriba)
legend = list(
title = list(text = "<b>Continente</b>"),
font = list(color = "#e0e6ed", size = 11),
bgcolor = "rgba(10, 14, 26, 0.9)",
bordercolor = "#00e5ff",
borderwidth = 1,
x = 1.05,
y = 0.8,
traceorder = "normal"
),
# Leyenda de tamaño (abajo) - CREAR MANUALMENTE
annotations = list(
# Título de leyenda de tamaño
list(
x = 1.05,
y = 0.45,
xref = "paper",
yref = "paper",
text = "<b style='color:#00e5ff; font-size:12px;'>Suscripciones Móviles</b>",
showarrow = FALSE,
xanchor = "left",
yanchor = "middle",
font = list(size = 12, color = "#00e5ff")
),
# Círculo pequeño
list(
x = 1.02,
y = 0.4,
xref = "paper",
yref = "paper",
text = "●",
showarrow = FALSE,
xanchor = "center",
yanchor = "middle",
font = list(size = 15, color = "#8b92a0")
),
# Texto pequeño
list(
x = 1.08,
y = 0.4,
xref = "paper",
yref = "paper",
text = "20",
showarrow = FALSE,
xanchor = "left",
yanchor = "middle",
font = list(size = 10, color = "#e0e6ed")
),
# Círculo mediano
list(
x = 1.02,
y = 0.35,
xref = "paper",
yref = "paper",
text = "●",
showarrow = FALSE,
xanchor = "center",
yanchor = "middle",
font = list(size = 20, color = "#8b92a0")
),
# Texto mediano
list(
x = 1.08,
y = 0.35,
xref = "paper",
yref = "paper",
text = "50",
showarrow = FALSE,
xanchor = "left",
yanchor = "middle",
font = list(size = 10, color = "#e0e6ed")
),
# Círculo grande
list(
x = 1.02,
y = 0.3,
xref = "paper",
yref = "paper",
text = "●",
showarrow = FALSE,
xanchor = "center",
yanchor = "middle",
font = list(size = 25, color = "#8b92a0")
),
# Texto grande
list(
x = 1.08,
y = 0.3,
xref = "paper",
yref = "paper",
text = "100",
showarrow = FALSE,
xanchor = "left",
yanchor = "middle",
font = list(size = 10, color = "#e0e6ed")
),
# Círculo muy grande
list(
x = 1.02,
y = 0.25,
xref = "paper",
yref = "paper",
text = "●",
showarrow = FALSE,
xanchor = "center",
yanchor = "middle",
font = list(size = 30, color = "#8b92a0")
),
# Texto muy grande
list(
x = 1.08,
y = 0.25,
xref = "paper",
yref = "paper",
text = "150+",
showarrow = FALSE,
xanchor = "left",
yanchor = "middle",
font = list(size = 10, color = "#e0e6ed")
),
# Nota explicativa
list(
x = 1.05,
y = 0.18,
xref = "paper",
yref = "paper",
text = "<span style='color:#8b92a0; font-size:10px;'>(por 100 habitantes)</span>",
showarrow = FALSE,
xanchor = "left",
yanchor = "middle"
)
),
hoverlabel = list(
bgcolor = "rgba(10, 14, 26, 0.95)",
bordercolor = "#00e5ff",
font = list(color = "#e0e6ed", size = 12, family = "Arial")
),
font = list(family = "Arial", color = "#e0e6ed"),
margin = list(l = 50, r = 200, b = 50, t = 100)
) %>%
config(
responsive = TRUE,
displayModeBar = TRUE,
displaylogo = FALSE,
modeBarButtonsToRemove = list('lasso2d', 'select2d'),
toImageButtonOptions = list(
format = "png",
filename = "infraestructura_digital_final",
width = 1200,
height = 800
)
)
plotly_plot <- plotly_plot %>%
style(showlegend = FALSE, traces = c(2:6)) # Ocultar leyendas de tamaño
plotly_plot# Asignar continentes
asignar_continentes <- function(data) {
continentes_map <- c(
"Argentina" = "Americas", "Bahamas, The" = "Americas", "Barbados" = "Americas",
"Belize" = "Americas", "Bolivia" = "Americas", "Brazil" = "Americas",
"Canada" = "Americas", "Chile" = "Americas", "Colombia" = "Americas",
"Costa Rica" = "Americas", "Cuba" = "Americas", "Dominica" = "Americas",
"Dominican Republic" = "Americas", "Ecuador" = "Americas", "El Salvador" = "Americas",
"Grenada" = "Americas", "Guatemala" = "Americas", "Guyana" = "Americas",
"Haiti" = "Americas", "Honduras" = "Americas", "Jamaica" = "Americas",
"Mexico" = "Americas", "Nicaragua" = "Americas", "Panama" = "Americas",
"Paraguay" = "Americas", "Peru" = "Americas", "St. Kitts and Nevis" = "Americas",
"St. Lucia" = "Americas", "St. Vincent and the Grenadines" = "Americas",
"Suriname" = "Americas", "Trinidad and Tobago" = "Americas", "United States" = "Americas",
"Uruguay" = "Americas", "Venezuela, RB" = "Americas", "Antigua and Barbuda" = "Americas",
"Albania" = "Europe", "Austria" = "Europe", "Belarus" = "Europe",
"Belgium" = "Europe", "Bosnia and Herzegovina" = "Europe", "Bulgaria" = "Europe",
"Croatia" = "Europe", "Cyprus" = "Europe", "Czech Republic" = "Europe",
"Czechia" = "Europe", "Denmark" = "Europe", "Estonia" = "Europe",
"Finland" = "Europe", "France" = "Europe", "Germany" = "Europe",
"Greece" = "Europe", "Hungary" = "Europe", "Iceland" = "Europe",
"Ireland" = "Europe", "Italy" = "Europe", "Kosovo" = "Europe",
"Latvia" = "Europe", "Lithuania" = "Europe", "Luxembourg" = "Europe",
"Malta" = "Europe", "Montenegro" = "Europe", "Netherlands" = "Europe",
"North Macedonia" = "Europe", "Norway" = "Europe", "Poland" = "Europe",
"Portugal" = "Europe", "Russian Federation" = "Europe", "Serbia" = "Europe",
"Slovak Republic" = "Europe", "Slovakia" = "Europe", "Slovenia" = "Europe",
"Spain" = "Europe", "Sweden" = "Europe", "Switzerland" = "Europe",
"Turkey" = "Europe", "Turkiye" = "Europe", "Ukraine" = "Europe",
"United Kingdom" = "Europe", "Armenia" = "Europe", "Azerbaijan" = "Europe",
"Georgia" = "Europe", "Moldova" = "Europe", "Romania" = "Europe",
"San Marino" = "Europe",
"Afghanistan" = "Asia", "Bahrain" = "Asia", "Bangladesh" = "Asia",
"Bhutan" = "Asia", "Brunei Darussalam" = "Asia", "Cambodia" = "Asia",
"China" = "Asia", "Hong Kong SAR, China" = "Asia", "India" = "Asia",
"Indonesia" = "Asia", "Iran, Islamic Rep." = "Asia", "Iraq" = "Asia",
"Israel" = "Asia", "Japan" = "Asia", "Jordan" = "Asia",
"Kazakhstan" = "Asia", "Korea, Dem. People's rep." = "Asia", "Korea, Rep." = "Asia",
"Kuwait" = "Asia", "Kyrgyz Republic" = "Asia", "Lao PDR" = "Asia",
"Lebanon" = "Asia", "Macao SAR, China" = "Asia", "Malaysia" = "Asia",
"Maldives" = "Asia", "Mongolia" = "Asia", "Myanmar" = "Asia",
"Nepal" = "Asia", "Oman" = "Asia", "Pakistan" = "Asia",
"Philippines" = "Asia", "Qatar" = "Asia", "Saudi Arabia" = "Asia",
"Singapore" = "Asia", "Sri Lanka" = "Asia", "Syrian Arab Republic" = "Asia",
"Taiwan" = "Asia", "Tajikistan" = "Asia", "Thailand" = "Asia",
"Timor-Leste" = "Asia", "Turkmenistan" = "Asia", "United Arab Emirates" = "Asia",
"Uzbekistan" = "Asia", "Vietnam" = "Asia", "Viet Nam" = "Asia",
"West Bank and Gaza" = "Asia", "Yemen, Rep." = "Asia",
"Algeria" = "Africa", "Angola" = "Africa", "Benin" = "Africa",
"Botswana" = "Africa", "Burkina Faso" = "Africa", "Burundi" = "Africa",
"Cabo Verde" = "Africa", "Cameroon" = "Africa", "Central African Republic" = "Africa",
"Chad" = "Africa", "Comoros" = "Africa", "Congo, Dem. Rep." = "Africa",
"Congo, Rep." = "Africa", "Cote d'Ivoire" = "Africa", "Djibouti" = "Africa",
"Egypt, Arab Rep." = "Africa", "Equatorial Guinea" = "Africa", "Eritrea" = "Africa",
"Eswatini" = "Africa", "Ethiopia" = "Africa", "Gabon" = "Africa",
"Gambia, The" = "Africa", "Ghana" = "Africa", "Guinea" = "Africa",
"Guinea-Bissau" = "Africa", "Kenya" = "Africa", "Lesotho" = "Africa",
"Liberia" = "Africa", "Libya" = "Africa", "Madagascar" = "Africa",
"Malawi" = "Africa", "Mali" = "Africa", "Mauritania" = "Africa",
"Mauritius" = "Africa", "Morocco" = "Africa", "Mozambique" = "Africa",
"Namibia" = "Africa", "Niger" = "Africa", "Nigeria" = "Africa",
"Rwanda" = "Africa", "Senegal" = "Africa", "Sierra Leone" = "Africa",
"Somalia" = "Africa", "South Africa" = "Africa", "South Sudan" = "Africa",
"Sudan" = "Africa", "Tanzania" = "Africa", "Togo" = "Africa",
"Tunisia" = "Africa", "Uganda" = "Africa", "Zambia" = "Africa",
"Zimbabwe" = "Africa",
"Australia" = "Oceania", "Fiji" = "Oceania", "Kiribati" = "Oceania",
"Marshall Islands" = "Oceania", "Micronesia, Fed. Sts." = "Oceania",
"New Zealand" = "Oceania", "Palau" = "Oceania", "Samoa" = "Oceania",
"Solomon Islands" = "Oceania", "Tonga" = "Oceania", "Vanuatu" = "Oceania"
)
data %>%
mutate(Continente = ifelse(Pais %in% names(continentes_map),
continentes_map[Pais], NA))
}
# Preparar datos con tamaño optimizado
datos_ambiental <- Base_2022 %>%
asignar_continentes() %>%
filter(
!is.na(`Area boscosa`) &
!is.na(`Tierra cultivable`) &
!is.na(Poblacion) &
!is.na(Continente)
) %>%
select(
Pais, Continente,
`Area boscosa`,
`Tierra cultivable`,
Poblacion
) %>%
mutate(
# Tamaño optimizado - usar raíz cúbica para mejor distribución
Tamaño = Poblacion^(1/3),
# Escalar el tamaño para un rango más manejable
Tamaño_escalado = 10 + (Tamaño - min(Tamaño)) / (max(Tamaño) - min(Tamaño)) * 30,
Hover = paste0(
"<b style='font-size:14px; color:#00e5ff;'>", Pais, "</b><br>",
"<span style='color:#a259ff; font-size:12px;'>", Continente, "</span><br><br>",
"<b style='color:#e0e6ed; font-size:12px;'>USO DE TIERRA:</b><br>",
"├─ Área Boscosa: <b style='color:#00e676;'>",
round(`Area boscosa`, 1), "%</b><br>",
"├─ Tierra Cultivable: <b style='color:#ffd600;'>",
round(`Tierra cultivable`, 1), "%</b><br>",
"├─ Balance: <b style='color:#00e5ff;'>",
round(`Area boscosa` + `Tierra cultivable`, 1), "% (bosque + cultivo)</b><br>",
"└─ Población: <b style='color:#ff1744;'>",
format(round(Poblacion/1e6, 1), big.mark = ",", trim = TRUE), " M</b>"
)
)
# Colores por continente
color_map <- c(
"Africa" = "#ff1744",
"Americas" = "#00e676",
"Asia" = "#ffd600",
"Europe" = "#0084ff",
"Oceania" = "#a259ff"
)
# Crear scatter plot con burbujas optimizadas
p <- plot_ly() %>%
add_trace(
data = datos_ambiental,
x = ~`Area boscosa`,
y = ~`Tierra cultivable`,
size = ~Tamaño_escalado, # Usar tamaño escalado
color = ~Continente,
colors = color_map,
type = "scatter",
mode = "markers",
customdata = ~Hover,
hovertemplate = "%{customdata}<extra></extra>",
marker = list(
sizeref = 0.1, # Ajuste manual para reducir tamaño general
sizemin = 3, # Tamaño mínimo reducido
opacity = 0.7, # Opacidad ajustada
line = list(
color = "#ffffff",
width = 1.5 # Borde más definido
)
),
showlegend = TRUE
) %>%
layout(
title = list(
text = "<b style='color:#00e5ff; font-size:24px;'>Sostenibilidad Ambiental: Uso de Tierra</b><br>
<span style='color:#8b92a0; font-size:14px;'>Año 2022 | Tamaño de burbuja = Población | Balance entre conservación y agricultura</span>",
x = 0.5,
xanchor = 'center',
y = 0.95
),
xaxis = list(
title = "<b style='font-size:16px;'>Área Boscosa (% de tierra)</b>",
gridcolor = '#12161f',
showgrid = TRUE,
zeroline = FALSE,
tickfont = list(color = '#8b92a0', size = 13),
titlefont = list(color = '#e0e6ed', size = 16),
range = c(0, 100) # Rango empezando en 0
),
yaxis = list(
title = "<b style='font-size:16px;'>Tierra Cultivable (% de tierra)</b>",
gridcolor = '#12161f',
showgrid = TRUE,
zeroline = FALSE,
tickfont = list(color = '#8b92a0', size = 13),
titlefont = list(color = '#e0e6ed', size = 16),
range = c(0, 70) # Rango empezando en 0
),
plot_bgcolor = '#000000',
paper_bgcolor = '#0a0e1a',
font = list(family = "Arial, sans-serif", color = '#e0e6ed', size = 13),
legend = list(
title = list(text = "<b style='font-size:14px;'>Continente</b>", font = list(size = 14, color = "#00e5ff")),
bgcolor = 'rgba(10,14,26,0.95)',
bordercolor = '#00e5ff',
borderwidth = 1.5,
x = 0.02,
y = 0.98,
font = list(size = 12, color = "#e0e6ed")
),
# Márgenes optimizados
margin = list(l = 100, r = 50, b = 120, t = 120),
hovermode = 'closest',
# ZONAS DE INTERPRETACIÓN CON MEJOR VISIBILIDAD
shapes = list(
# Zona CONSERVACIÓN
list(
type = "rect",
x0 = 60, x1 = 100,
y0 = 0, y1 = 20,
xref = "x", yref = "y",
fillcolor = "rgba(0, 230, 118, 0.1)",
line = list(color = "rgba(0, 230, 118, 0.6)", width = 2, dash = "dot"),
layer = "below"
),
# Zona AGRÍCOLA
list(
type = "rect",
x0 = 0, x1 = 30,
y0 = 40, y1 = 70,
xref = "x", yref = "y",
fillcolor = "rgba(255, 214, 0, 0.1)",
line = list(color = "rgba(255, 214, 0, 0.6)", width = 2, dash = "dot"),
layer = "below"
),
# Zona BALANCE
list(
type = "rect",
x0 = 30, x1 = 60,
y0 = 20, y1 = 40,
xref = "x", yref = "y",
fillcolor = "rgba(0, 132, 255, 0.1)",
line = list(color = "rgba(0, 132, 255, 0.6)", width = 2, dash = "dot"),
layer = "below"
),
# Zona CRÍTICA
list(
type = "rect",
x0 = 0, x1 = 30,
y0 = 0, y1 = 20,
xref = "x", yref = "y",
fillcolor = "rgba(255, 23, 68, 0.1)",
line = list(color = "rgba(255, 23, 68, 0.6)", width = 2, dash = "dot"),
layer = "below"
)
),
annotations = list(
# Zona CONSERVACIÓN
list(
x = 82, y = 10,
text = "<b style='color:#00e676; font-size:12px;'>🌲 CONSERVACIÓN</b>",
showarrow = FALSE,
bgcolor = "rgba(0, 230, 118, 0.2)",
bordercolor = "#00e676",
borderwidth = 1.5,
borderpad = 6,
font = list(size = 11)
),
# Zona AGRÍCOLA
list(
x = 25, y = 65,
text = "<b style='color:#ffd600; font-size:12px;'>🌾 AGRÍCOLA</b>",
showarrow = FALSE,
bgcolor = "rgba(255, 214, 0, 0.2)",
bordercolor = "#ffd600",
borderwidth = 1.5,
borderpad = 6,
font = list(size = 11)
),
# Zona BALANCE
list(
x = 60, y = 40,
text = "<b style='color:#0084ff; font-size:12px;'>⚖️ BALANCE</b>",
showarrow = FALSE,
bgcolor = "rgba(0, 132, 255, 0.2)",
bordercolor = "#0084ff",
borderwidth = 1.5,
borderpad = 6,
font = list(size = 11)
),
# Zona CRÍTICA
list(
x = 15, y = 20,
text = "<b style='color:#ff1744; font-size:12px;'>⚠️ CRÍTICA</b>",
showarrow = FALSE,
bgcolor = "rgba(255, 23, 68, 0.2)",
bordercolor = "#ff1744",
borderwidth = 1.5,
borderpad = 6,
font = list(size = 10)
),
# Interpretación mejorada
list(
x = 0.5, y = -0.15,
xref = "paper", yref = "paper",
text = "<span style='color:#8b92a0; font-size:12px;'><b>🌍 INTERPRETACIÓN:</b> Burbujas más grandes = mayor población. Verde = alta cobertura boscosa. Amarillo = alta agricultura. Equilibrio = desarrollo sostenible.</span>",
showarrow = FALSE,
xanchor = "center",
yanchor = "top",
font = list(size = 11, color = "#8b92a0")
)
)
) %>%
config(
responsive = TRUE,
displayModeBar = TRUE,
displaylogo = FALSE,
modeBarButtonsToRemove = list('lasso2d', 'select2d'),
toImageButtonOptions = list(
format = "png",
filename = "sostenibilidad_ambiental_2022",
width = 1600,
height = 1000
)
)
pasignar_continentes <- function(data) {
continentes_map <- c(
"Argentina" = "Americas", "Bahamas, The" = "Americas", "Barbados" = "Americas",
"Belize" = "Americas", "Bolivia" = "Americas", "Brazil" = "Americas",
"Canada" = "Americas", "Chile" = "Americas", "Colombia" = "Americas",
"Costa Rica" = "Americas", "Cuba" = "Americas", "Dominica" = "Americas",
"Dominican Republic" = "Americas", "Ecuador" = "Americas", "El Salvador" = "Americas",
"Grenada" = "Americas", "Guatemala" = "Americas", "Guyana" = "Americas",
"Haiti" = "Americas", "Honduras" = "Americas", "Jamaica" = "Americas",
"Mexico" = "Americas", "Nicaragua" = "Americas", "Panama" = "Americas",
"Paraguay" = "Americas", "Peru" = "Americas", "St. Kitts and Nevis" = "Americas",
"St. Lucia" = "Americas", "St. Vincent and the Grenadines" = "Americas",
"Suriname" = "Americas", "Trinidad and Tobago" = "Americas", "United States" = "Americas",
"Uruguay" = "Americas", "Venezuela, RB" = "Americas", "Antigua and Barbuda" = "Americas",
"Albania" = "Europe", "Austria" = "Europe", "Belarus" = "Europe",
"Belgium" = "Europe", "Bosnia and Herzegovina" = "Europe", "Bulgaria" = "Europe",
"Croatia" = "Europe", "Cyprus" = "Europe", "Czech Republic" = "Europe",
"Czechia" = "Europe", "Denmark" = "Europe", "Estonia" = "Europe",
"Finland" = "Europe", "France" = "Europe", "Germany" = "Europe",
"Greece" = "Europe", "Hungary" = "Europe", "Iceland" = "Europe",
"Ireland" = "Europe", "Italy" = "Europe", "Kosovo" = "Europe",
"Latvia" = "Europe", "Lithuania" = "Europe", "Luxembourg" = "Europe",
"Malta" = "Europe", "Montenegro" = "Europe", "Netherlands" = "Europe",
"North Macedonia" = "Europe", "Norway" = "Europe", "Poland" = "Europe",
"Portugal" = "Europe", "Russian Federation" = "Europe", "Serbia" = "Europe",
"Slovak Republic" = "Europe", "Slovakia" = "Europe", "Slovenia" = "Europe",
"Spain" = "Europe", "Sweden" = "Europe", "Switzerland" = "Europe",
"Turkey" = "Europe", "Turkiye" = "Europe", "Ukraine" = "Europe",
"United Kingdom" = "Europe", "Armenia" = "Europe", "Azerbaijan" = "Europe",
"Georgia" = "Europe", "Moldova" = "Europe", "Romania" = "Europe",
"San Marino" = "Europe",
"Afghanistan" = "Asia", "Bahrain" = "Asia", "Bangladesh" = "Asia",
"Bhutan" = "Asia", "Brunei Darussalam" = "Asia", "Cambodia" = "Asia",
"China" = "Asia", "Hong Kong SAR, China" = "Asia", "India" = "Asia",
"Indonesia" = "Asia", "Iran, Islamic Rep." = "Asia", "Iraq" = "Asia",
"Israel" = "Asia", "Japan" = "Asia", "Jordan" = "Asia",
"Kazakhstan" = "Asia", "Korea, Dem. People's rep." = "Asia", "Korea, Rep." = "Asia",
"Kuwait" = "Asia", "Kyrgyz Republic" = "Asia", "Lao PDR" = "Asia",
"Lebanon" = "Asia", "Macao SAR, China" = "Asia", "Malaysia" = "Asia",
"Maldives" = "Asia", "Mongolia" = "Asia", "Myanmar" = "Asia",
"Nepal" = "Asia", "Oman" = "Asia", "Pakistan" = "Asia",
"Philippines" = "Asia", "Qatar" = "Asia", "Saudi Arabia" = "Asia",
"Singapore" = "Asia", "Sri Lanka" = "Asia", "Syrian Arab Republic" = "Asia",
"Taiwan" = "Asia", "Tajikistan" = "Asia", "Thailand" = "Asia",
"Timor-Leste" = "Asia", "Turkmenistan" = "Asia", "United Arab Emirates" = "Asia",
"Uzbekistan" = "Asia", "Vietnam" = "Asia", "Viet Nam" = "Asia",
"West Bank and Gaza" = "Asia", "Yemen, Rep." = "Asia",
"Algeria" = "Africa", "Angola" = "Africa", "Benin" = "Africa",
"Botswana" = "Africa", "Burkina Faso" = "Africa", "Burundi" = "Africa",
"Cabo Verde" = "Africa", "Cameroon" = "Africa", "Central African Republic" = "Africa",
"Chad" = "Africa", "Comoros" = "Africa", "Congo, Dem. Rep." = "Africa",
"Congo, Rep." = "Africa", "Cote d'Ivoire" = "Africa", "Djibouti" = "Africa",
"Egypt, Arab Rep." = "Africa", "Equatorial Guinea" = "Africa", "Eritrea" = "Africa",
"Eswatini" = "Africa", "Ethiopia" = "Africa", "Gabon" = "Africa",
"Gambia, The" = "Africa", "Ghana" = "Africa", "Guinea" = "Africa",
"Guinea-Bissau" = "Africa", "Kenya" = "Africa", "Lesotho" = "Africa",
"Liberia" = "Africa", "Libya" = "Africa", "Madagascar" = "Africa",
"Malawi" = "Africa", "Mali" = "Africa", "Mauritania" = "Africa",
"Mauritius" = "Africa", "Morocco" = "Africa", "Mozambique" = "Africa",
"Namibia" = "Africa", "Niger" = "Africa", "Nigeria" = "Africa",
"Rwanda" = "Africa", "Senegal" = "Africa", "Sierra Leone" = "Africa",
"Somalia" = "Africa", "South Africa" = "Africa", "South Sudan" = "Africa",
"Sudan" = "Africa", "Tanzania" = "Africa", "Togo" = "Africa",
"Tunisia" = "Africa", "Uganda" = "Africa", "Zambia" = "Africa",
"Zimbabwe" = "Africa",
"Australia" = "Oceania", "Fiji" = "Oceania", "Kiribati" = "Oceania",
"Marshall Islands" = "Oceania", "Micronesia, Fed. Sts." = "Oceania",
"New Zealand" = "Oceania", "Palau" = "Oceania", "Samoa" = "Oceania",
"Solomon Islands" = "Oceania", "Tonga" = "Oceania", "Vanuatu" = "Oceania"
)
data %>%
mutate(Continente = ifelse(Pais %in% names(continentes_map),
continentes_map[Pais], NA))
}
# ====== PREPARAR DATOS - ESTRUCTURA SIMPLE COMO TU EJEMPLO ======
datos_riesgos <- Base_2022 %>%
asignar_continentes() %>%
filter(
!is.na(`Crecimiento poblacion`) &
!is.na(Poblacion) &
!is.na(Continente) &
Poblacion > 0
) %>%
select(
Pais, Continente,
Poblacion,
`Crecimiento poblacion`,
`Mortalidad infantil`,
`Esperanza vida`,
PIB_per
) %>%
arrange(desc(Poblacion)) %>%
slice_head(n = 60) %>%
mutate(
Poblacion_millones = Poblacion / 1e6,
# Clasificación simplificada
Clasificacion = case_when(
`Crecimiento poblacion` > 2 ~ "Dividendo Demográfico",
`Crecimiento poblacion` >= 0.5 & `Crecimiento poblacion` <= 2 ~ "Madurez Estable",
`Crecimiento poblacion` < 0.5 ~ "Declive Poblacional",
TRUE ~ "Sin Clasificar"
),
tooltip = paste0(
"<b style='font-size:14px; color:#00e5ff;'>", Pais, "</b><br>",
"<span style='color:#a259ff; font-size:12px;'>", Continente, "</span><br><br>",
"<b style='color:#e0e6ed; font-size:12px;'>INDICADORES DEMOGRÁFICOS:</b><br>",
"├─ Población: <b style='color:#ffd600;'>",
format(round(Poblacion_millones, 1), big.mark = ",", decimal.mark = ".", trim = TRUE), " M</b><br>",
"├─ Crecimiento: <b style='color:#00e676;'>",
round(`Crecimiento poblacion`, 2), "%</b><br>",
"├─ Esperanza Vida: <b style='color:#00e5ff;'>",
round(`Esperanza vida`, 1), " años</b><br>",
"├─ Mortalidad Infantil: <b style='color:#ff1744;'>",
round(`Mortalidad infantil`, 1), "/1000</b><br>",
"└─ PIB per cápita: <b style='color:#a259ff;'>$",
format(round(PIB_per), big.mark = ","), "</b><br>",
"<br><b>Clasificación:</b> <span style='color:#00e676;'>", Clasificacion, "</span>"
)
)
# Verificar datos
cat("Países procesados:", nrow(datos_riesgos), "\n")## Países procesados: 60
# ====== CREAR TREEMAP SIMPLE - SIN JERARQUÍA COMPLEJA ======
fig_treemap <- plot_ly(
data = datos_riesgos,
type = "treemap",
labels = ~Pais,
parents = ~"", # TODOS los países bajo el mismo padre - como tu ejemplo exitoso
values = ~Poblacion,
branchvalues = "total",
marker = list(
colors = ~`Crecimiento poblacion`,
colorscale = list(
c(0, "#ff1744"), # Rojo para declive
c(0.3, "#ff6b00"), # Naranja
c(0.5, "#fdd835"), # Amarillo para transición
c(0.7, "#76ff03"), # Verde claro
c(1, "#00e676") # Verde para alto crecimiento
),
cmin = -2, # Rango más realista para crecimiento poblacional
cmax = 4,
showscale = TRUE,
colorbar = list(
title = list(
text = "<b>Crecimiento<br>Anual (%)</b>",
font = list(size = 12, color = "#e0e6ed")
),
tickvals = c(-2, -1, 0, 1, 2, 3, 4),
ticktext = c("-2%", "-1%", "0%", "1%", "2%", "3%", "4%"),
thickness = 20,
len = 0.8,
x = 1.05, # Posición ajustada
y = 0.5,
tickfont = list(size = 11, color = "#8b92a0")
),
line = list(color = "#0a0e1a", width = 2),
opacity = 0.9
),
textinfo = "label+value",
texttemplate = "<b>%{label}</b><br>%{value:.0f}M",
textposition = "middle center",
textfont = list(
size = 14,
color = "white",
family = "Arial"
),
customdata = ~tooltip,
hovertemplate = "%{customdata}<extra></extra>",
showlegend = FALSE
)
# ====== LAYOUT OPTIMIZADO ======
fig_treemap <- fig_treemap %>%
layout(
title = list(
text = "<b style='color:#00e5ff; font-size:24px;'>Oportunidades y Riesgos Demográficos Globales</b><br>
<span style='color:#8b92a0; font-size:14px;'>Top 60 países | Tamaño = Población | Color = Crecimiento Anual (2022)</span>",
x = 0.5,
xanchor = 'center',
y = 0.95
),
plot_bgcolor = '#000000',
paper_bgcolor = '#0a0e1a',
font = list(family = "Arial, sans-serif", color = '#e0e6ed', size = 12),
# Márgenes optimizados para evitar invasión del toc
margin = list(l = 10, r = 150, b = 100, t = 120),
# Anotaciones explicativas
annotations = list(
list(
x = 0.5,
y = -0.08,
xref = "paper",
yref = "paper",
text = "<span style='color:#e0e6ed; font-size:12px;'><b>📊 LECTURA:</b>
<span style='color:#00e676;'>Verde (alto crecimiento) = Oportunidades demográficas</span> |
<span style='color:#ff1744;'>Rojo (bajo/negativo) = Riesgos de declive</span> |
<span style='color:#fdd835;'>Amarillo = Transición estable</span></span>",
showarrow = FALSE,
xanchor = "center",
align = "center"
)
)
) %>%
config(
responsive = TRUE,
displayModeBar = TRUE,
displaylogo = FALSE,
modeBarButtonsToRemove = list('lasso2d', 'select2d'),
toImageButtonOptions = list(
format = "png",
filename = "oportunidades_riesgos_demograficos",
width = 1600,
height = 1000
)
)
# Mostrar el gráfico
fig_treemapvariables_mapa <- list(
"Crecimiento PIB" = "Crecimiento PIB",
"Acceso electricidad" = "Acceso electricidad",
"Crecimiento poblacion" = "Crecimiento poblacion"
)
world <- ne_countries(scale = "medium", returnclass = "sf")
mapeo_paises <- c(
"United States of America" = "United States",
"Russia" = "Russian Federation",
"South Korea" = "Korea, Rep.",
"North Korea" = "Korea, Dem. People's Rep.",
"Egypt" = "Egypt, Arab Rep.",
"Democratic Republic of the Congo" = "Congo, Dem. Rep.",
"Republic of the Congo" = "Congo, Rep.",
"Laos" = "Lao PDR",
"Syria" = "Syrian Arab Republic",
"Venezuela" = "Venezuela, RB",
"Iran" = "Iran, Islamic Rep.",
"Czech Republic" = "Czechia",
"Slovakia" = "Slovak Republic",
"Kyrgyzstan" = "Kyrgyz Republic",
"Yemen" = "Yemen, Rep.",
"Turkey" = "Turkiye",
"Gambia" = "Gambia, The",
"Bahamas" = "Bahamas, The",
"Ivory Coast" = "Cote d'Ivoire",
"Brunei" = "Brunei Darussalam",
"Cape Verde" = "Cabo Verde",
"Hong Kong" = "Hong Kong SAR, China",
"Macao" = "Macao SAR, China",
"Macedonia" = "North Macedonia",
"Saint Lucia" = "St. Lucia",
"Saint Vincent and the Grenadines" = "St. Vincent and the Grenadines",
"Saint Kitts and Nevis" = "St. Kitts and Nevis",
"Myanmar" = "Myanmar",
"Bolivia" = "Bolivia",
"Libya" = "Libya",
"Tanzania" = "Tanzania",
"Eswatini" = "Eswatini",
"Timor-Leste" = "Timor-Leste"
)
mapeo_df <- data.frame(
name_world = names(mapeo_paises),
name_data = unname(mapeo_paises),
stringsAsFactors = FALSE
)
world_data <- world %>%
left_join(mapeo_df, by = c("name" = "name_world")) %>%
left_join(
Base_2022 %>% select(Pais, all_of(unlist(variables_mapa))),
by = c("name_data" = "Pais")
) %>%
mutate(
across(
all_of(unlist(variables_mapa)),
~ifelse(is.na(.) & name %in% Base_2022$Pais,
Base_2022[[cur_column()]][match(name, Base_2022$Pais)], .)
)
)paletas <- list(
"Crecimiento PIB" = colorNumeric(
palette = colorRampPalette(c("#ff1744", "#ff6b00", "#ffd600", "#00e676", "#00e5ff"))(100),
domain = world_data$`Crecimiento PIB`,
na.color = "#1a1a2e"
),
"Acceso electricidad" = colorNumeric(
palette = colorRampPalette(c("#1a1a2e", "#0084ff", "#00e5ff", "#00e676", "#ffd600"))(100),
domain = world_data$`Acceso electricidad`,
na.color = "#1a1a2e"
),
"Crecimiento poblacion" = colorNumeric(
palette = colorRampPalette(c("#0084ff", "#00e5ff", "#a259ff", "#ff6b00", "#ff1744"))(100),
domain = world_data$`Crecimiento poblacion`, # ✅ CORREGIDO
na.color = "#1a1a2e"
)
)
mapa <- leaflet(world_data,
width = "100%",
height = "550px",
options = leafletOptions(
minZoom = 2,
maxZoom = 7,
worldCopyJump = TRUE
)) %>%
setView(lng = 15, lat = 20, zoom = 2.2) %>%
addProviderTiles("CartoDB.DarkMatter")
for (var_display in names(variables_mapa)) {
var_col <- variables_mapa[[var_display]]
pal <- paletas[[var_display]]
unidad <- if(grepl("Crecimiento", var_display)) "%" else "%"
labels <- sprintf(
"<div style='font-family: sans-serif;'>
<strong style='color: #00e5ff; font-size: 15px;'>%s</strong><br/>
<span style='color: #8b92a0; font-size: 12px;'>%s:</span><br/>
<strong style='color: #00e5ff; font-size: 14px;'>%s</strong>
</div>",
world_data$name,
var_display,
ifelse(is.na(world_data[[var_col]]),
"Sin datos",
paste0(round(world_data[[var_col]], 2), unidad))
) %>% lapply(HTML)
mapa <- mapa %>%
addPolygons(
fillColor = ~pal(world_data[[var_col]]),
weight = 1.2,
opacity = 0.9,
color = "#00e5ff",
fillOpacity = 0.75,
highlight = highlightOptions(
weight = 2.5,
color = "#00ffff",
fillOpacity = 0.9,
bringToFront = TRUE
),
label = labels,
labelOptions = labelOptions(
style = list(
"background" = "rgba(10, 14, 26, 0.95)",
"border" = "2px solid #00e5ff",
"border-radius" = "6px",
"padding" = "10px",
"box-shadow" = "0 0 15px rgba(0, 229, 255, 0.6)"
),
textsize = "13px"
),
group = var_display
)
}
mapa <- mapa %>%
addLayersControl(
baseGroups = names(variables_mapa),
options = layersControlOptions(collapsed = FALSE),
position = "topleft"
) %>%
hideGroup(names(variables_mapa)[-1])
mapa <- mapa %>%
htmlwidgets::onRender("
function(el, x) {
var map = this;
// Configuración de leyendas
var legendConfigs = {
'Crecimiento PIB': {
title: 'CRECIMIENTO DEL PIB',
subtitle: '(% anual)',
min: -10,
max: 10,
colors: ['#ff1744', '#ff6b00', '#ffd600', '#00e676', '#00e5ff'],
labels: ['-10%', '-5%', '0%', '5%', '10%']
},
'Acceso electricidad': {
title: 'ACCESO A ELECTRICIDAD',
subtitle: '(% de población)',
min: 0,
max: 100,
colors: ['#1a1a2e', '#0084ff', '#00e5ff', '#00e676', '#ffd600'],
labels: ['0%', '25%', '50%', '75%', '100%']
},
'Crecimiento poblacion': {
title: 'CRECIMIENTO POBLACIÓN',
subtitle: '(% anual)',
min: -2,
max: 4,
colors: ['#0084ff', '#00e5ff', '#a259ff', '#ff6b00', '#ff1744'],
labels: ['-2%', '-1%', '0%', '2%', '4%']
}
};
// Crear leyenda
var LegendControl = L.Control.extend({
options: { position: 'bottomright' },
onAdd: function(map) {
var div = L.DomUtil.create('div', 'info legend');
div.id = 'bar-legend';
return div;
}
});
map.addControl(new LegendControl());
// Función para crear barra de gradiente
function updateLegend(varName) {
var div = document.getElementById('bar-legend');
var config = legendConfigs[varName];
// Crear gradiente CSS
var gradient = 'linear-gradient(to right';
config.colors.forEach(function(color) {
gradient += ', ' + color;
});
gradient += ')';
var html = '<div style=\"background: linear-gradient(135deg, #0a0e1a, #12161f); padding: 18px; border-radius: 10px; border: 2px solid #00e5ff; box-shadow: 0 8px 32px rgba(0,0,0,0.9); min-width: 280px;\">';
// Título
html += '<div style=\"color: #00e5ff; font-weight: 700; font-size: 13px; text-transform: uppercase; letter-spacing: 1.2px; margin-bottom: 4px; text-align: center; text-shadow: 0 0 10px rgba(0,229,255,0.5);\">' + config.title + '</div>';
html += '<div style=\"color: #8b92a0; font-size: 11px; text-align: center; margin-bottom: 12px;\">' + config.subtitle + '</div>';
// Barra de color
html += '<div style=\"height: 20px; background: ' + gradient + '; border-radius: 4px; border: 1px solid #00e5ff; margin-bottom: 8px; box-shadow: inset 0 0 10px rgba(0,0,0,0.5);\"></div>';
// Etiquetas
html += '<div style=\"display: flex; justify-content: space-between; font-size: 11px; color: #e0e6ed;\">';
config.labels.forEach(function(label) {
html += '<span>' + label + '</span>';
});
html += '</div>';
html += '</div>';
div.innerHTML = html;
}
// Inicializar
updateLegend('Crecimiento PIB');
// Actualizar al cambiar capa
map.on('baselayerchange', function(e) {
updateLegend(e.name);
});
// Estilizar control de capas
setTimeout(function() {
var ctrl = document.querySelector('.leaflet-control-layers');
if (ctrl) {
ctrl.style.background = 'linear-gradient(135deg, #0a0e1a, #12161f)';
ctrl.style.border = '2px solid rgba(0, 229, 255, 0.4)';
ctrl.style.borderRadius = '10px';
ctrl.style.padding = '18px';
ctrl.style.boxShadow = '0 8px 32px rgba(0, 0, 0, 0.9)';
}
var base = document.querySelector('.leaflet-control-layers-base');
if (base && !document.getElementById('sel-title')) {
var title = document.createElement('div');
title.id = 'sel-title';
title.innerHTML = '<strong style=\"color: #00e5ff; font-size: 13px; text-transform: uppercase; letter-spacing: 1.5px; text-shadow: 0 0 10px rgba(0,229,255,0.5);\">📊 SELECCIONA VARIABLE</strong>';
title.style.marginBottom = '12px';
title.style.paddingBottom = '10px';
title.style.borderBottom = '2px solid rgba(0, 229, 255, 0.3)';
base.insertBefore(title, base.firstChild);
}
var labels = document.querySelectorAll('.leaflet-control-layers-base label');
labels.forEach(function(label, idx) {
label.style.color = '#e0e6ed';
label.style.fontSize = '13px';
label.style.fontWeight = '600';
label.style.padding = '9px 12px';
label.style.margin = '4px 0';
label.style.display = 'block';
label.style.borderRadius = '6px';
label.style.cursor = 'pointer';
label.style.transition = 'all 0.3s';
var input = label.querySelector('input');
if (input) {
input.style.accentColor = '#00e5ff';
if (idx === 0) {
label.style.background = 'rgba(0, 229, 255, 0.15)';
label.style.color = '#00e5ff';
}
}
label.addEventListener('mouseenter', function() {
this.style.background = 'rgba(0, 229, 255, 0.1)';
this.style.color = '#00e5ff';
});
label.addEventListener('mouseleave', function() {
if (!this.querySelector('input').checked) {
this.style.background = 'transparent';
this.style.color = '#e0e6ed';
}
});
});
var inputs = document.querySelectorAll('.leaflet-control-layers-base input');
inputs.forEach(function(input) {
input.addEventListener('change', function() {
labels.forEach(function(l) {
l.style.background = 'transparent';
l.style.color = '#e0e6ed';
});
if (this.checked) {
this.parentElement.style.background = 'rgba(0, 229, 255, 0.15)';
this.parentElement.style.color = '#00e5ff';
}
});
});
}, 100);
}
")
mapa